#include<iostream>
#include<stdlib.h>
#include<string>
#include<cmath>
#define pi 3.141592653589793238
using namespace std;

double f(double x,int func)
{
   double y;
   double b=2*pi*11.5/360;
   switch(func)
   {
     case 1:
        y=1/x-tan(x);
        break;
     case 2:
        y=1/x-pow(2,x);
        break;
     case 3:
        y=pow(2,-x)+exp(x)+2*cos(x)-6;
        break;
     case 4:
        y=(pow(x,3)+4*pow(x,2)+3*x+5)/(2*pow(x,3)-9*pow(x,2)+18*x-2);
        break;
     case 5:
        y=tan(x);
        break;
     case 6:
        y=sin(x/2)-1;
        break;
     case 7:
        y=exp(x)-tan(x);
        break;
     case 8:
        y=pow(x,3)-12*pow(x,2)+3*x+1;
        break;
     case 9:
        y=0.5*pi-asin(x)-x*sqrt(1-x*x)-1.24;
        break;
     case 10:
        y=89*sin(b)*sin(x)*cos(x)+89*cos(b)*sin(x)*sin(x)-(76.5*sin(b)-27.5*tan(b))*cos(x)-(76.5*cos(b)-27.5)*sin(x);
        break;
     case 11:
        y=89*sin(b)*sin(x)*cos(x)+89*cos(b)*sin(x)*sin(x)-(64*sin(b)-15*tan(b))*cos(x)-(64*cos(b)-15)*sin(x);
        break;
   }
   return y;
}

double ff(double x,int func)
{
   double y;
   double b=2*pi*11.5/360;
   switch(func)
   {
     case 5:
        y=1/pow(cos(x),2);
        break;
     case 9:
        y=-1/sqrt(1-x*x)-sqrt(1-x*x)+x*x/sqrt(1-x*x);
        break;
     case 10:
        y=89*sin(b)*cos(2*x)+89*cos(b)*2*sin(x)*cos(x)+(76.5*sin(b)-27.5*tan(b))*sin(x)-(76.5*cos(b)-27.5)*cos(x);
        break;
     case 11:
        y=89*sin(b)*cos(2*x)+89*cos(b)*2*sin(x)*cos(x)+(64*sin(b)-15*tan(b))*sin(x)-(64*cos(b)-15)*cos(x);
        break;
   }
   return y;
}

class equationsolver
{
  public:
         virtual void solve(double x,double y,int func)=0;
};

class bisection : public equationsolver
{
  private:
         int m;
	 double t;
         double n;
  public:
         double x;
         bisection(int _m,double _n,double _t)
         {
            m=_m;n=_n;t=_t;
         }
	 virtual void solve(double a,double b,int func);
};

class newtonmethod : public equationsolver
{
  private:
	 int m;
	 double n;
  public:
         double x;
         newtonmethod(int _m,double _n)
         {
            m=_m;n=_n;
         }
	 virtual void solve(double x0,double non,int func);
};

class secantmethod : public equationsolver
{
  private:
         int m;
	 double n;
	 double t;
  public:
         double x;
         secantmethod(int _m,double _n,double _t)
         {
            m=_m;n=_n;t=_t;
         }
	 virtual void solve(double x0,double x1,int func);
};

void bisection::solve(double a,double b,int func)
{
   double u=f(a,func);
   double v=f(b,func);
   double h;
   double c;
   double w;
   int k;
   for(k=1;k<m+1;k++)
   {
      h=b-a;
      c=a+h/2;
      w=f(c,func);
      if ((h*h<n)or(w*w<t))
	 break;
      else if (w*u<0)
      {
	 b=c;
         v=w;
      }
      else
      {
	 a=c;
         u=w;
      }
   }
   x=c;
}

void newtonmethod::solve(double x0,double non,int func)
{
   double y=x0;
   double u;
   int k;
   for(k=0;k<m+1;k++)
   {
      u=f(y,func);
      if (u*u<n)
         break;
      y=y-u/ff(y,func);
   }
   x=y;
}


void secantmethod::solve(double x0,double x1,int func)
{
   double xn=x1;
   double xm=x0;
   double y;
   double s;
   double u=f(xn,func);
   double v=f(xm,func);
   int k;
   for (k=2;k<m+1;k++)
   {
      if (u*u>v*v)
      {
         y=xm;
	 xm=xn;
	 xn=y;
	 u=f(xn,func);
	 v=f(xm,func);
      }
      s=(xn-xm)/(u-v);
      xm=xn;
      v=u;
      xn=xn-u*s;
      u=f(xn,func);
      if (((xn-xm)*(xn-xm)<n)or(u*u<t))
         break;
   }
   x=xn;
}

int main()
{
   bisection bis1(10,0.001,0.001);
   bisection bis2(10,0.001,0.001);
   bisection bis3(10,0.001,0.001);
   bisection bis4(10,0.001,0.001);
   bisection bis5(10,0.001,0.001);
   
   newtonmethod newt1(10,0.001);
   newtonmethod newt2(10,0.001);
   newtonmethod newt3(10,0.001);
   newtonmethod newt4(10,0.001);
   
   secantmethod sec1(10,0.001,0.001);
   secantmethod sec2(10,0.001,0.001);
   secantmethod sec3(10,0.001,0.001);
   secantmethod sec4(10,0.001,0.001);
   secantmethod sec5(10,0.001,0.001);
   
   bis1.solve(0,pi/2,1);
   bis2.solve(0,1,2);
   bis3.solve(1,3,3);
   bis4.solve(0,4,4);
   newt1.solve(6,0,5);
   sec1.solve(0,pi/2,6);
   sec2.solve(1,1.4,7);
   sec3.solve(0,-0.5,8);
   
   cout<<"B1:"<<bis1.x<<endl;
   cout<<"B2:"<<bis2.x<<endl;
   cout<<"B3:"<<bis3.x<<endl;
   cout<<"B4:"<<bis4.x<<endl;
   cout<<"C:"<<newt1.x<<endl;
   cout<<"D1:"<<sec1.x<<endl;
   cout<<"D2:"<<sec2.x<<endl;
   cout<<"D3:"<<sec3.x<<endl;

   sec1.solve(3.0,3.1,6);
   sec2.solve(1.2,1.3,7);
   sec3.solve(-0.2,-0.18,8);
   cout<<"D1(3.0,3.1):"<<sec1.x<<endl;
   cout<<"D2(1.2,1.3):"<<sec2.x<<endl;
   cout<<"D3(-0,2,-0.18):"<<sec3.x<<endl;
 
   bis5.solve(0,1,9);
   newt2.solve(0,0,9);
   sec4.solve(0,0.5,9);
   cout<<"E1(bis):"<<bis5.x<<endl;
   cout<<"E2(newt):"<<newt2.x<<endl;
   cout<<"E3(sec):"<<sec4.x<<endl;

   newt3.solve(2*pi*33/360,0,10);
   newt4.solve(2*pi*33/360,0,11);
   sec5.solve(2*pi*33/360,2*pi*33/360+pi,11);
   cout<<"F1:"<<newt3.x<<endl;
   cout<<"F1(度):"<<newt3.x*180/pi<<endl;
   cout<<"F2:"<<newt4.x<<endl;
   cout<<"F2(度):"<<newt4.x*180/pi<<endl;
   cout<<"F3:"<<newt4.x<<endl;
   cout<<"F3(度):"<<sec5.x*180/pi<<endl;

   return 0;
}
